package utils

import (
	"errors"
	"fmt"
	"gin_study_blog/common"
	"github.com/golang-jwt/jwt/v5"
	"strconv"
	"time"
)

// 声明自己的 key

type JwtUser struct {
	// Identity 用户唯一标识
	Username string `json:"username"`
	NickName string `json:"nick_name"`
	Role     int    `json:"role"` // 用户权限 1 管理人 2 用户 3 游客
	UserID   uint   `json:"user_id"`
}

type UserClaims struct {
	// 内嵌标准的声明
	JwtUser
	jwt.RegisteredClaims
}

// GenUserToken
// 生成 token
func GenUserToken(user JwtUser) (string, error) {
	var myKey = []byte(common.Config.Jwt.Secret)
	// 创建一个我们自己声明的数据
	expire, _ := strconv.ParseInt(common.Config.Jwt.Expires, 10, 64)
	duration := time.Hour * time.Duration(expire)

	userClaim := UserClaims{
		user,
		jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(time.Now().Add(duration)), // 定义到期时间
			Issuer:    common.Config.Jwt.Issuer,
		},
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, userClaim)
	tokenString, err := token.SignedString(myKey)
	if err != nil {
		return "", err
	}
	return tokenString, err
}

// ParseToken
// 解析 token
func ParseToken(tokenString string) (*UserClaims, error) {
	var myKey = []byte(common.Config.Jwt.Secret)
	// 解析 token
	token, err := jwt.ParseWithClaims(tokenString, &UserClaims{}, func(token *jwt.Token) (interface{}, error) {
		return myKey, nil
	})

	if err != nil {
		common.Log.Error(fmt.Sprintf("token parse err: %s", err.Error()))
		return nil, err
	}
	// token.Claims.(*UserClaims) 内存断言 是否存在错误
	if claims, ok := token.Claims.(*UserClaims); ok && token.Valid {
		return claims, nil
	}
	return nil, errors.New("invalid token")
}
